package com.yanxu.lock.fairandunfair;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 折戟沉沙铁未销
 * @version V1.0
 * @date 2025/3/16-2025
 * @Description: 公平锁
 */
public class FairLock {
    public static void main(String[] args) throws InterruptedException {
        PrintQueue1 printQueue = new PrintQueue1();
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+" 开始打印!!!");
                    printQueue.printJob("");
                    System.out.println(Thread.currentThread().getName()+" 打印完毕!!!");
                }
            },"线程"+i).start();
            Thread.sleep(100);
        }
    }
}

class PrintQueue1 {
    //定义一个公平锁
    Lock lock = new ReentrantLock(true);

    public void printJob(Object document) {
        //第一次打印
        lock.lock();
        try {
            int duration = new Random().nextInt(10) + 1;
            System.out.println(Thread.currentThread().getName() + "第一次，正在打印，需要" + duration + " 秒时间!!!");
            Thread.sleep(duration * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        //第二次打印
        lock.lock();
        try {
            int duration = new Random().nextInt(10) + 1;
            System.out.println(Thread.currentThread().getName() + "第二次，正在打印，需要" + duration + " 秒时间!!!");
            Thread.sleep(duration * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /*
    *   线程0 开始打印!!!
        线程0第一次，正在打印，需要4 秒时间!!!
        线程1 开始打印!!!
        线程2 开始打印!!!
        线程3 开始打印!!!
        线程4 开始打印!!!
        线程1第一次，正在打印，需要1 秒时间!!!
        线程2第一次，正在打印，需要9 秒时间!!!
        线程3第一次，正在打印，需要9 秒时间!!!
        线程4第一次，正在打印，需要3 秒时间!!!
        线程0第二次，正在打印，需要1 秒时间!!!
        线程0 打印完毕!!!
        线程1第二次，正在打印，需要3 秒时间!!!
        线程1 打印完毕!!!
        线程2第二次，正在打印，需要1 秒时间!!!
        线程2 打印完毕!!!
        线程3第二次，正在打印，需要6 秒时间!!!
        线程3 打印完毕!!!
        线程4第二次，正在打印，需要5 秒时间!!!
        线程4 打印完毕!!!
    *
    *  这就是公平锁的体现。
    *   一个线程打印两次，第一次打印完毕，然后释放了锁，他就必须去等待队列中排队。
    *   直到其他所有线程全部完成了第一次打印，才又轮到了它，它才能继续第二次打印。
    *
    * */
}